Houdiniメモ : VEX : 4次元立方体を表示する
Houdiniで4次元(XYZW)の立方体を表示してみました。
X, Y, Z, W軸に平行な軸をそれぞれ、赤、緑、青、白に着色しています。
https://gyazo.com/f4111936fed3b38543a3417ef4a81a25
関連
ネットワーク
■AttributeWrangle(4次元立方体の表示)
https://gyazo.com/816db21245fe675f9f778a16a76f3ac7
4次元立方体の3次元空間への写像を表示しています。
回転させると面白い動きがみられるので、X軸-W軸の回転処理も入れています。
code:HeperCube(c)
vector4 n = normalize(chp("camera_direction")); // カメラの向きベクトル(4次元)
vector4 cubePos = chp("cube_pos"); // 4次元立方体の位置(4次元)
float k = chf("focal_length"); // 焦点距離
// 4次元立方体の頂点
vector4 v[] =
{
{ 1, 1, 1, 1},
{ 1, 1, 1, -1},
{ 1, 1, -1, 1},
{ 1, 1, -1, -1},
{ 1, -1, 1, 1},
{ 1, -1, 1, -1},
{ 1, -1, -1, 1},
{ 1, -1, -1, -1},
{-1, 1, 1, 1},
{-1, 1, 1, -1},
{-1, 1, -1, 1},
{-1, 1, -1, -1},
{-1, -1, 1, 1},
{-1, -1, 1, -1},
{-1, -1, -1, 1},
{-1, -1, -1, -1},
};
// X-W軸の回転行列
float radian_XW = chf("radian_XW");
int X = 0, Y = 1, Z = 2, W = 3;
matrix rot = ident();
setcomp(rot, cos(radian_XW), X, X);
setcomp(rot, -sin(radian_XW), X, W);
setcomp(rot, sin(radian_XW), W, X);
setcomp(rot, cos(radian_XW), W, W);
// 4次元立方体の各頂点の3次元空間への射影を求める
for (int i = 0; i < len(v); i++) {
vector4 ray = rot * vi + cubePos; float L = k * dot(n, n) / dot(n, ray);
vector p = L * set(ray.x, ray.y, ray.z);
addpoint(geoself(), p);
}
// 軸ごとにグループ分けをする
string groupX = "X";
string groupY = "Y";
string groupZ = "Z";
string groupW = "W";
// X軸に平行な辺の追加
setprimgroup(geoself(), groupX, addprim(geoself(), "polyline", 0, 8), 1);
setprimgroup(geoself(), groupX, addprim(geoself(), "polyline", 1, 9), 1);
setprimgroup(geoself(), groupX, addprim(geoself(), "polyline", 2, 10), 1);
setprimgroup(geoself(), groupX, addprim(geoself(), "polyline", 3, 11), 1);
setprimgroup(geoself(), groupX, addprim(geoself(), "polyline", 4, 12), 1);
setprimgroup(geoself(), groupX, addprim(geoself(), "polyline", 5, 13), 1);
setprimgroup(geoself(), groupX, addprim(geoself(), "polyline", 6, 14), 1);
setprimgroup(geoself(), groupX, addprim(geoself(), "polyline", 7, 15), 1);
// Y軸に平行な辺の追加
setprimgroup(geoself(), groupY, addprim(geoself(), "polyline", 0, 4), 1);
setprimgroup(geoself(), groupY, addprim(geoself(), "polyline", 1, 5), 1);
setprimgroup(geoself(), groupY, addprim(geoself(), "polyline", 2, 6), 1);
setprimgroup(geoself(), groupY, addprim(geoself(), "polyline", 3, 7), 1);
setprimgroup(geoself(), groupY, addprim(geoself(), "polyline", 8, 12), 1);
setprimgroup(geoself(), groupY, addprim(geoself(), "polyline", 9, 13), 1);
setprimgroup(geoself(), groupY, addprim(geoself(), "polyline", 10, 14), 1);
setprimgroup(geoself(), groupY, addprim(geoself(), "polyline", 11, 15), 1);
// Z軸に平行な辺の追加
setprimgroup(geoself(), groupZ, addprim(geoself(), "polyline", 0, 2), 1);
setprimgroup(geoself(), groupZ, addprim(geoself(), "polyline", 1, 3), 1);
setprimgroup(geoself(), groupZ, addprim(geoself(), "polyline", 4, 6), 1);
setprimgroup(geoself(), groupZ, addprim(geoself(), "polyline", 5, 7), 1);
setprimgroup(geoself(), groupZ, addprim(geoself(), "polyline", 8, 10), 1);
setprimgroup(geoself(), groupZ, addprim(geoself(), "polyline", 9, 11), 1);
setprimgroup(geoself(), groupZ, addprim(geoself(), "polyline", 12, 14), 1);
setprimgroup(geoself(), groupZ, addprim(geoself(), "polyline", 13, 15), 1);
// W軸に平行な辺の追加
setprimgroup(geoself(), groupW, addprim(geoself(), "polyline", 0, 1), 1);
setprimgroup(geoself(), groupW, addprim(geoself(), "polyline", 2, 3), 1);
setprimgroup(geoself(), groupW, addprim(geoself(), "polyline", 4, 5), 1);
setprimgroup(geoself(), groupW, addprim(geoself(), "polyline", 6, 7), 1);
setprimgroup(geoself(), groupW, addprim(geoself(), "polyline", 8, 9), 1);
setprimgroup(geoself(), groupW, addprim(geoself(), "polyline", 10, 11), 1);
setprimgroup(geoself(), groupW, addprim(geoself(), "polyline", 12, 13), 1);
setprimgroup(geoself(), groupW, addprim(geoself(), "polyline", 14, 15), 1);
■AttributeWrangle(着色)
https://gyazo.com/e4d51d350bc8677cdf9421317a12f1f7
グループごとに色分けしています。
code:color(c)
if (@group_X) { @Cd = {1, 0, 0}; } // X軸に平行な辺
if (@group_Y) { @Cd = {0, 1, 0}; } // Y軸に平行な辺
if (@group_Z) { @Cd = {0, 0, 1}; } // Z軸に平行な辺
if (@group_W) { @Cd = {1, 1, 1}; } // W軸に平行な辺